diff --git a/swh/web/ui/converters.py b/swh/web/ui/converters.py
--- a/swh/web/ui/converters.py
+++ b/swh/web/ui/converters.py
@@ -181,6 +181,8 @@
                         dates={'date', 'committer_date'})
 
     if revision:
+        if 'parents' in revision:
+            revision['merge'] = len(revision['parents']) > 1
         if 'message' in revision:
             try:
                 revision['message'] = revision['message'].decode('utf-8')
diff --git a/swh/web/ui/main.py b/swh/web/ui/main.py
--- a/swh/web/ui/main.py
+++ b/swh/web/ui/main.py
@@ -11,6 +11,7 @@
 
 from swh.web.ui.renderers import RENDERERS, urlize_api_links
 from swh.web.ui.renderers import safe_docstring_display
+from swh.web.ui.renderers import revision_id_from_url
 from swh.storage import get_storage
 
 
@@ -32,7 +33,7 @@
 app = FlaskAPI(__name__)
 app.jinja_env.filters['urlize_api_links'] = urlize_api_links
 app.jinja_env.filters['safe_docstring_display'] = safe_docstring_display
-
+app.jinja_env.filters['revision_id_from_url'] = revision_id_from_url
 
 AUTODOC_ENDPOINT_INSTALLED = False
 
diff --git a/swh/web/ui/renderers.py b/swh/web/ui/renderers.py
--- a/swh/web/ui/renderers.py
+++ b/swh/web/ui/renderers.py
@@ -92,6 +92,12 @@
     return re.sub(src, dest, docstring)
 
 
+def revision_id_from_url(url):
+    """Utility function to obtain a revision's ID from its browsing URL."""
+    return re.sub(r'/browse/revision/([0-9a-f]{40}|[0-9a-f]{64})/.*',
+                  r'\1', url)
+
+
 class SWHBrowsableAPIRenderer(renderers.BrowsableAPIRenderer):
     """SWH's browsable api renderer.
 
diff --git a/swh/web/ui/templates/revision-log.html b/swh/web/ui/templates/revision-log.html
--- a/swh/web/ui/templates/revision-log.html
+++ b/swh/web/ui/templates/revision-log.html
@@ -3,133 +3,154 @@
 {% block content %}
 
 {% if message is not none %}
+<div class="swh-message">
   {{ message }}
+</div>
 {% endif %}
 
-  <div class="container">
-    <h2>Queried revision:</h2>
-    {% if sha1_git is not none %}
-    <div>Revision with git SHA1 <a href="{{ sha1_url }}">{{ sha1_git }}</a></div>
-    {% else %}
-    <div><a href="{{ origin_url }}">Origin ID {{ origin_id }}</a></div>
-    <div>Branch name {{ branch_name }}</div>
-    {% if timestamp is not none %}
-    <div>Time stamp {{ timestamp }}</div>
-    {% endif %}
-    <div>
-    </div>
-    {% endif %}
-  </div>
+<div class="container">
+  <h2>Queried revision:</h2>
+  {% if sha1_git is not none %}
+  <div>Revision with git SHA1 <a href="{{ sha1_url }}">{{ sha1_git }}</a></div>
+  {% else %}
+  <div><a href="{{ origin_url }}">Origin ID {{ origin_id }}</a></div>
+  <div>Branch name {{ branch_name }}</div>
+  {% if timestamp is not none %}
+  <div>Time stamp {{ timestamp }}</div>
+  {% endif %}
+  {% endif %}
+</div>
 
 {% if revisions is not none %}
+<div class="container">
   {% for revision in revisions %}
-
-  <div class="container">
-    {% if revision['url'] is not none %}
-    <div class="row">
-       <div class="col-md-2">Revision</div>
-       <div class="col-md-6"><p><a href="{{ revision['url'] }}">{{ revision['url'] }}</a></p></div>
+  {% if revision['merge'] %}
+  <div class="row">
+    <div class="col-md-2">
+      Merge
+    </div>
+    <div class="col-md-6">
+      {% for url in revision['parent_urls'] %}
+      <a href={{ url }}>{{ url | revision_id_from_url }}</a>
+      {% endfor %}
     </div>
-    {% endif %}
+  </div>
+  {% endif %}
+
+  {% if revision['url'] is not none %}
+  <div class="row">
+    <div class="col-md-2">Revision</div>
+    <div class="col-md-6"><p><a href="{{ revision['url'] }}">{{ revision['url']  }}</a></p></div>
+  </div>
+  {% endif %}
 
-    {% if revision['history_url'] is not none %}
-    <div class="row">
-       <div class="col-md-2">Revision Log</div>
-       <div class="col-md-6"><p><a href="{{ revision['history_url'] }}">{{ revision['history_url'] }}</a></p></div>
+  {% if revision['history_url'] is not none %}
+  <div class="row">
+    <div class="col-md-2">Revision Log</div>
+    <div class="col-md-6"><p><a href="{{ revision['history_url'] }}">{{ revision['history_url'] }}</a></p></div>
+  </div>
+  {% endif %}
+
+  {% if revision['history_context_url'] is not none %}
+  <div class="row">
+    <div class="col-md-2">Contextual Revision Log</div>
+    <div class="col-md-6"><p><a href="{{ revision['history_context_url'] }}">{{ revision['history_context_url'] }}</a></p></div>
+  </div>
+  {% endif %}
+
+  {% if revision['directory_url'] is not none %}
+  <div class="row">
+    <div class="col-md-2">directory</div>
+    <div class="col-md-6"><p><a href="{{ revision['directory_url'] }}">{{ revision['directory_url'] }}</a></p></div>
+  </div>
+  {% endif %}
+
+  {% if revision['author'] is not none %}
+  <div class="row">
+    <div class="col-md-2">Author</div>
+    <div class="col-md-6">
+      <p>
+	<a href="{{ revision['author_url'] }}">{{ revision['author']['name'] }}</a>
+      {% if 'decoding_failures' in revision['author'] %}(some decoding errors){% endif %}
+      </p>
     </div>
-    {% endif %}
+  </div>
+  <div class="row">
+    <div class="col-md-2">Date</div>
+    <div class="col-md-6"><p>{{ revision['date'] }}</p></div>
+  </div>
+  {% endif %}
 
-    {% if revision['history_context_url'] is not none %}
-    <div class="row">
-       <div class="col-md-2">Contextual Revision Log</div>
-       <div class="col-md-6"><p><a href="{{ revision['history_context_url'] }}">{{ revision['history_context_url'] }}</a></p></div>
+  {% if revision['committer'] is not none %}
+  <div class="row">
+    <div class="col-md-2">Committer</div>
+    <div class="col-md-6">
+      <p>
+	<a href="{{ revision['committer_url'] }}">{{ revision['committer']['name'] }}</a>
+	{% if 'decoding_failures' in revision['committer'] %}(some decoding errors){% endif %}
+      </p>
     </div>
-    {% endif %}
-    
-    {% if revision['directory_url'] is not none %}
-           <div class="row">
-              <div class="col-md-2">directory</div>
-              <div class="col-md-6"><p><a href="{{ revision['directory_url'] }}">{{ revision['directory_url'] }}</a></p></div>
-           </div>
-     {% endif %}
+  </div>
+  <div class="row">
+    <div class="col-md-2">Committer Date</div>
+    <div class="col-md-6"><p>{{ revision['committer_date'] }}</p></div>
+  </div>
+  {% endif %}
 
-    {% if revision['author'] is not none %}
-           <div class="row">
-              <div class="col-md-2">Author</div>
-              <div class="col-md-6">
-		<p>
-		  <a href="{{ revision['author_url'] }}">{{ revision['author']['name'] }}</a>
-		  {% if 'decoding_failures' in revision['author'] %}(some decoding errors){% endif %}
-		</p>
-	      </div>
-           </div>
-           <div class="row">
-              <div class="col-md-2">Date</div>
-              <div class="col-md-6"><p>{{ revision['date'] }}</p></div>
-           </div>
-    {% endif %}
+  {% if revision['message'] is not none %}
+  <div class="row">
+    <div class="col-md-2">Message</div>
+    <div class="col-md-6"><pre>{{ revision['message'] }}</pre></div>
+  </div>
+  {% elif revision['message_encoding_failed'] %}
+  <div class="row">
+    <div class="col-md-2">Message</div>
+    <div class="col-md-6"><a href="{{ revision['message_url'] }}">Download raw message</a></div>
+  </div>
+  {% else %}
+  <div class="row">
+    <div class="col-md-2">Message</div>
+    <div class="col-md-6">No message found.</div>
+  </div>
+  {% endif %}
 
-    {% if revision['committer'] is not none %}
-           <div class="row">
-              <div class="col-md-2">Committer</div>
-              <div class="col-md-6">
-		<p>
-		  <a href="{{ revision['committer_url'] }}">{{ revision['committer']['name'] }}</a>
-		  {% if 'decoding_failures' in revision['committer'] %}(some decoding errors){% endif %}
-		</p>
-	      </div>
-           </div>
-           <div class="row">
-              <div class="col-md-2">Committer Date</div>
-              <div class="col-md-6"><p>{{ revision['committer_date'] }}</p></div>
-           </div>
-    {% endif %}
+  {% for key in revision.keys() %}
+  {% if key in ['type', 'synthetic'] and key not in ['decoding_failures'] and revision[key] is not none %}
+  <div class="row">
+    <div class="col-md-2">{{ key }}</div>
+    <div class="col-md-6"><pre>{{ revision[key] }}</pre></div>
+  </div>
+  {% endif %}
+  {% endfor %}
 
-    {% if revision['message'] is not none %}
-            <div class="row">
-              <div class="col-md-2">Message</div>
-              <div class="col-md-6"><pre>{{ revision['message'] }}</pre></div>
-            </div>
-    {% elif revision['message_encoding_failed'] %}
-	    <div class="row">
-              <div class="col-md-2">Message</div>
-              <div class="col-md-6"><a href="{{ revision['message_url'] }}">Download raw message</a></div>
-            </div
-    {% else %}
-            <div class="row">
-              <div class="col-md-2">Message</div>
-              <div class="col-md-6">No message found.</div>
-            </div>
-    {% endif %}	    
-	    
-    {% for key in revision.keys() %}
-           {% if key in ['type', 'synthetic'] and key not in ['decoding_failures'] and revision[key] is not none %}
-            <div class="row">
-              <div class="col-md-2">{{ key }}</div>
-              <div class="col-md-6"><p>{{ revision[key] }}</pre></div>
-            </div>
-           {% endif %}
+  {% for key in ['children_urls', 'parent_urls'] %}
+  {% if revision[key] is not none %}
+  <div class="row">
+    <div class="col-md-2">{{ key }}</div>    
+    {% for link in revision[key] %}
+    <div class="col-md-6"><a href="{{ link }}">{{ link }}</a></div>
     {% endfor %}
-    {% for key in ['parent_urls', 'children_urls'] %}
-        {% if revision[key] is not none %}
-         <div class="row">
-            <div class="col-md-2">{{ key }}</div>
-            {% for link in revision[key] %}
-            <div class="col-md-6"><a href="{{ link }}">{{ link }}</a></div>
-            {% endfor %}
-         </div>
-        {% endif %}
-    {% endfor %}
-	 {% if 'decoding_failures' in revision %}
-	 <div class="row">
-	   <div class="col-md-10">(some decoding errors occurred)</div>
-	 </div>
-	 {% endif %}
-
   </div>
+  {% endif %}
+  {% endfor %}
+  
+  {% if 'decoding_failures' in revision %}
+  <div class="row">
+    <div class="col-md-10">(some decoding errors occurred)</div>
+  </div>
+  {% endif %}
   <hr />
   {% endfor %}
-
-{% endif %}
-
+  
+  {% if next_revs_url is not none %}
+  <span class="pull-right">
+    <a href="{{ next_revs_url }}" class="btn btn-primary">
+      Next revisions
+      <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
+    </a>
+  </span>
+  {% endif %}
+  {% endif %}
+</div>
+<hr />
 {% endblock %}
diff --git a/swh/web/ui/tests/test_converters.py b/swh/web/ui/tests/test_converters.py
--- a/swh/web/ui/tests/test_converters.py
+++ b/swh/web/ui/tests/test_converters.py
@@ -344,6 +344,122 @@
                     '309d36484e7edf7bb912'
                 }]
             },
+            'merge': True
+        }
+
+        # when
+        actual_revision = converters.from_revision(revision_input)
+
+        # then
+        self.assertEqual(actual_revision, expected_revision)
+
+    @istest
+    def from_revision_nomerge(self):
+        revision_input = {
+            'id': hashutil.hex_to_hash(
+                '18d8be353ed3480476f032475e7c233eff7371d5'),
+            'parents': [
+                hashutil.hex_to_hash(
+                    '29d8be353ed3480476f032475e7c244eff7371d5')
+            ]
+        }
+
+        expected_revision = {
+            'id': '18d8be353ed3480476f032475e7c233eff7371d5',
+            'parents': [
+                '29d8be353ed3480476f032475e7c244eff7371d5'
+            ],
+            'merge': False
+        }
+
+        # when
+        actual_revision = converters.from_revision(revision_input)
+
+        # then
+        self.assertEqual(actual_revision, expected_revision)
+
+    @istest
+    def from_revision_noparents(self):
+        revision_input = {
+            'id': hashutil.hex_to_hash(
+                '18d8be353ed3480476f032475e7c233eff7371d5'),
+            'directory': hashutil.hex_to_hash(
+                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
+            'author': {
+                'name': b'Software Heritage',
+                'fullname': b'robot robot@softwareheritage.org',
+                'email': b'robot@softwareheritage.org',
+            },
+            'committer': {
+                'name': b'Software Heritage',
+                'fullname': b'robot robot@softwareheritage.org',
+                'email': b'robot@softwareheritage.org',
+            },
+            'message': b'synthetic revision message',
+            'date': {
+                'timestamp': datetime.datetime(
+                    2000, 1, 17, 11, 23, 54,
+                    tzinfo=datetime.timezone.utc).timestamp(),
+                'offset': 0,
+                'negative_utc': False,
+            },
+            'committer_date': {
+                'timestamp': datetime.datetime(
+                    2000, 1, 17, 11, 23, 54,
+                    tzinfo=datetime.timezone.utc).timestamp(),
+                'offset': 0,
+                'negative_utc': False,
+            },
+            'synthetic': True,
+            'type': 'tar',
+            'children': [
+                hashutil.hex_to_hash(
+                    '123546353ed3480476f032475e7c244eff7371d5'),
+            ],
+            'metadata': {
+                'original_artifact': [{
+                    'archive_type': 'tar',
+                    'name': 'webbase-5.7.0.tar.gz',
+                    'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd',
+                    'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1',
+                    'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f'
+                    '309d36484e7edf7bb912',
+
+                }]
+            },
+        }
+
+        expected_revision = {
+            'id': '18d8be353ed3480476f032475e7c233eff7371d5',
+            'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
+            'author': {
+                'name': 'Software Heritage',
+                'fullname': 'robot robot@softwareheritage.org',
+                'email': 'robot@softwareheritage.org',
+            },
+            'committer': {
+                'name': 'Software Heritage',
+                'fullname': 'robot robot@softwareheritage.org',
+                'email': 'robot@softwareheritage.org',
+            },
+            'message': 'synthetic revision message',
+            'date': "2000-01-17T11:23:54+00:00",
+            'committer_date': "2000-01-17T11:23:54+00:00",
+            'children': [
+                '123546353ed3480476f032475e7c244eff7371d5'
+            ],
+            'type': 'tar',
+            'synthetic': True,
+            'metadata': {
+                'original_artifact': [{
+                    'archive_type': 'tar',
+                    'name': 'webbase-5.7.0.tar.gz',
+                    'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd',
+                    'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1',
+                    'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f'
+                    '309d36484e7edf7bb912'
+                }]
+            }
         }
 
         # when
@@ -445,6 +561,7 @@
                     '309d36484e7edf7bb912'
                 }]
             },
+            'merge': True
         }
 
         # when
diff --git a/swh/web/ui/tests/test_service.py b/swh/web/ui/tests/test_service.py
--- a/swh/web/ui/tests/test_service.py
+++ b/swh/web/ui/tests/test_service.py
@@ -14,6 +14,39 @@
 from swh.web.ui.tests import test_app
 
 
+REVISION_ID_BIN = hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5')
+REVISION_ID = '18d8be353ed3480476f032475e7c233eff7371d5'
+DIRECTORY_ID_BIN = hex_to_hash('7834ef7e7c357ce2af928115c6c6a42b7e2a44e6')
+DIRECTORY_ID = '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'
+AUTHOR_ID_BIN = {
+    'name': b'bill & boule',
+    'email': b'bill@boule.org',
+}
+AUTHOR_ID = {
+    'name': 'bill & boule',
+    'email': 'bill@boule.org',
+}
+COMMITTER_ID_BIN = {
+    'name': b'boule & bill',
+    'email': b'boule@bill.org',
+}
+COMMITTER_ID = {
+    'name': 'boule & bill',
+    'email': 'boule@bill.org',
+}
+SAMPLE_DATE_RAW = {
+    'timestamp': datetime.datetime(
+        2000, 1, 17, 11, 23, 54,
+        tzinfo=datetime.timezone.utc,
+    ).timestamp(),
+    'offset': 0,
+    'negative_utc': False,
+}
+SAMPLE_DATE = '2000-01-17T11:23:54+00:00'
+SAMPLE_MESSAGE_BIN = b'elegant fix for bug 31415957'
+SAMPLE_MESSAGE = 'elegant fix for bug 31415957'
+
+
 class ServiceTestCase(test_app.SWHApiTestCase):
 
     @patch('swh.web.ui.service.backend')
@@ -574,6 +607,7 @@
             'parents': [],
             'children': [hash_to_hex(b'999'), hash_to_hex(b'777')],
             'directory': hash_to_hex(b'278'),
+            'merge': False
         })
 
         mock_query.parse_hash_with_algorithms_or_throws.assert_has_calls(
@@ -646,6 +680,7 @@
             'parents': [],
             'children': [hash_to_hex(b'999'), hash_to_hex(b'777')],
             'directory': hash_to_hex(b'278'),
+            'merge': False
         })
 
         mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with(  # noqa
@@ -953,34 +988,13 @@
     def lookup_revision(self, mock_backend):
         # given
         mock_backend.revision_get = MagicMock(return_value={
-            'id': hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
-            'author': {
-                'name': b'bill & boule',
-                'email': b'bill@boule.org',
-            },
-            'committer': {
-                'name': b'boule & bill',
-                'email': b'boule@bill.org',
-            },
-            'message': b'elegant fix for bug 31415957',
-            'date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
-            'committer_date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
+            'id': REVISION_ID_BIN,
+            'directory': DIRECTORY_ID_BIN,
+            'author': AUTHOR_ID_BIN,
+            'committer': COMMITTER_ID_BIN,
+            'message': SAMPLE_MESSAGE_BIN,
+            'date': SAMPLE_DATE_RAW,
+            'committer_date': SAMPLE_DATE_RAW,
             'synthetic': False,
             'type': 'git',
             'parents': [],
@@ -989,31 +1003,26 @@
 
         # when
         actual_revision = service.lookup_revision(
-            '18d8be353ed3480476f032475e7c233eff7371d5')
+            REVISION_ID)
 
         # then
         self.assertEqual(actual_revision, {
-            'id': '18d8be353ed3480476f032475e7c233eff7371d5',
-            'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
-            'author': {
-                'name': 'bill & boule',
-                'email': 'bill@boule.org',
-            },
-            'committer': {
-                'name': 'boule & bill',
-                'email': 'boule@bill.org',
-            },
-            'message': 'elegant fix for bug 31415957',
-            'date': "2000-01-17T11:23:54+00:00",
-            'committer_date': "2000-01-17T11:23:54+00:00",
+            'id': REVISION_ID,
+            'directory': DIRECTORY_ID,
+            'author': AUTHOR_ID,
+            'committer': COMMITTER_ID,
+            'message': SAMPLE_MESSAGE,
+            'date': SAMPLE_DATE,
+            'committer_date': SAMPLE_DATE,
             'synthetic': False,
             'type': 'git',
             'parents': [],
             'metadata': [],
+            'merge': False
         })
 
         mock_backend.revision_get.assert_called_with(
-            hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'))
+            REVISION_ID_BIN)
 
     @patch('swh.web.ui.service.backend')
     @istest
@@ -1021,33 +1030,12 @@
         # given
         stub_rev = {
             'id': hex_to_hash('123456'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
-            'author': {
-                'name': b'bill & boule',
-                'email': b'bill@boule.org',
-            },
-            'committer': {
-                'name': b'boule & bill',
-                'email': b'boule@bill.org',
-            },
+            'directory': DIRECTORY_ID_BIN,
+            'author': AUTHOR_ID_BIN,
+            'committer': COMMITTER_ID_BIN,
             'message': b'elegant fix for bug \xff',
-            'date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
-            'committer_date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
+            'date': SAMPLE_DATE_RAW,
+            'committer_date': SAMPLE_DATE_RAW,
             'synthetic': False,
             'type': 'git',
             'parents': [],
@@ -1057,66 +1045,40 @@
 
         # when
         actual_revision = service.lookup_revision(
-            '18d8be353ed3480476f032475e7c233eff7371d5')
+            REVISION_ID)
 
         # then
         self.assertEqual(actual_revision, {
             'id': '123456',
-            'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
-            'author': {
-                'name': 'bill & boule',
-                'email': 'bill@boule.org',
-            },
-            'committer': {
-                'name': 'boule & bill',
-                'email': 'boule@bill.org',
-            },
+            'directory': DIRECTORY_ID,
+            'author': AUTHOR_ID,
+            'committer': COMMITTER_ID,
             'message': None,
             'message_decoding_failed': True,
-            'date': "2000-01-17T11:23:54+00:00",
-            'committer_date': "2000-01-17T11:23:54+00:00",
+            'date': SAMPLE_DATE,
+            'committer_date': SAMPLE_DATE,
             'synthetic': False,
             'type': 'git',
             'parents': [],
             'metadata': [],
+            'merge': False
         })
 
         mock_backend.revision_get.assert_called_with(
-            hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'))
+            REVISION_ID_BIN)
 
     @patch('swh.web.ui.service.backend')
     @istest
     def lookup_revision_msg_ok(self, mock_backend):
         # given
         mock_backend.revision_get.return_value = {
-            'id': hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
-            'author': {
-                'name': b'bill & boule',
-                'email': b'bill@boule.org',
-            },
-            'committer': {
-                'name': b'boule & bill',
-                'email': b'boule@bill.org',
-            },
-            'message': b'elegant fix for bug 31415957',
-            'date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
-            'committer_date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
+            'id': REVISION_ID_BIN,
+            'directory': DIRECTORY_ID_BIN,
+            'author': AUTHOR_ID_BIN,
+            'committer': COMMITTER_ID_BIN,
+            'message': SAMPLE_MESSAGE_BIN,
+            'date': SAMPLE_DATE_RAW,
+            'committer_date': SAMPLE_DATE_RAW,
             'synthetic': False,
             'type': 'git',
             'parents': [],
@@ -1125,45 +1087,24 @@
 
         # when
         rv = service.lookup_revision_message(
-            '18d8be353ed3480476f032475e7c233eff7371d5')
+            REVISION_ID)
 
         # then
-        self.assertEquals(rv, {'message': b'elegant fix for bug 31415957'})
+        self.assertEquals(rv, {'message': SAMPLE_MESSAGE_BIN})
         mock_backend.revision_get.assert_called_with(
-            hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'))
+            REVISION_ID_BIN)
 
     @patch('swh.web.ui.service.backend')
     @istest
     def lookup_revision_msg_absent(self, mock_backend):
         # given
         mock_backend.revision_get.return_value = {
-            'id': hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
-            'author': {
-                'name': b'bill & boule',
-                'email': b'bill@boule.org',
-            },
-            'committer': {
-                'name': b'boule & bill',
-                'email': b'boule@bill.org',
-            },
-            'date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
-            'committer_date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
+            'id': REVISION_ID_BIN,
+            'directory': DIRECTORY_ID_BIN,
+            'author': AUTHOR_ID_BIN,
+            'committer': COMMITTER_ID_BIN,
+            'date': SAMPLE_DATE_RAW,
+            'committer_date': SAMPLE_DATE_RAW,
             'synthetic': False,
             'type': 'git',
             'parents': [],
@@ -1173,11 +1114,11 @@
         # when
         with self.assertRaises(NotFoundExc) as cm:
             service.lookup_revision_message(
-                '18d8be353ed3480476f032475e7c233eff7371d5')
+                REVISION_ID)
 
             # then
             mock_backend.revision_get.assert_called_with(
-                hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'))
+                REVISION_ID_BIN)
             self.assertEqual(cm.exception.args[0], 'No message for revision '
                              'with sha1_git '
                              '18d8be353ed3480476f032475e7c233eff7371d5.')
@@ -1191,11 +1132,11 @@
         # when
         with self.assertRaises(NotFoundExc) as cm:
             service.lookup_revision_message(
-                '18d8be353ed3480476f032475e7c233eff7371d5')
+                REVISION_ID)
 
             # then
             mock_backend.revision_get.assert_called_with(
-                hex_to_hash('18d8be353ed3480476f032475e7c233eff7371d5'))
+                REVISION_ID_BIN)
             self.assertEqual(cm.exception.args[0], 'Revision with sha1_git '
                              '18d8be353ed3480476f032475e7c233eff7371d5 '
                              'not found.')
@@ -1205,37 +1146,19 @@
     def lookup_revision_multiple(self, mock_backend):
         # given
 
-        sha1_bin = '18d8be353ed3480476f032475e7c233eff7371d5'
+        sha1_bin = REVISION_ID
         sha1_other = 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'
 
         stub_revisions = [
             {
                 'id': hex_to_hash(sha1_bin),
-                'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
-                'author': {
-                    'name': b'bill & boule',
-                    'email': b'bill@boule.org',
-                },
-                'committer': {
-                    'name': b'boule & bill',
-                    'email': b'boule@bill.org',
-                },
-                'message': b'elegant fix for bug 31415957',
-                'date': {
-                    'timestamp': datetime.datetime(
-                        2000, 1, 17, 11, 23, 54,
-                        tzinfo=datetime.timezone.utc).timestamp(),
-                    'offset': 0,
-                    'negative_utc': False
-                    },
+                'directory': DIRECTORY_ID,
+                'author': AUTHOR_ID_BIN,
+                'committer': COMMITTER_ID_BIN,
+                'message': SAMPLE_MESSAGE_BIN,
+                'date': SAMPLE_DATE_RAW,
                 'date_offset': 0,
-                'committer_date': {
-                    'timestamp': datetime.datetime(
-                        2000, 1, 17, 11, 23, 54,
-                        tzinfo=datetime.timezone.utc).timestamp(),
-                    'offset': 0,
-                    'negative_utc': False
-                    },
+                'committer_date': SAMPLE_DATE_RAW,
                 'committer_date_offset': 0,
                 'synthetic': False,
                 'type': 'git',
@@ -1287,24 +1210,19 @@
         self.assertEqual(list(actual_revisions), [
             {
                 'id': sha1_bin,
-                'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
-                'author': {
-                    'name': 'bill & boule',
-                    'email': 'bill@boule.org',
-                },
-                'committer': {
-                    'name': 'boule & bill',
-                    'email': 'boule@bill.org',
-                },
-                'message': 'elegant fix for bug 31415957',
-                'date': '2000-01-17T11:23:54+00:00',
+                'directory': DIRECTORY_ID,
+                'author': AUTHOR_ID,
+                'committer': COMMITTER_ID,
+                'message': SAMPLE_MESSAGE,
+                'date': SAMPLE_DATE,
                 'date_offset': 0,
-                'committer_date': '2000-01-17T11:23:54+00:00',
+                'committer_date': SAMPLE_DATE,
                 'committer_date_offset': 0,
                 'synthetic': False,
                 'type': 'git',
                 'parents': [],
                 'metadata': [],
+                'merge': False
             },
             {
                 'id': sha1_other,
@@ -1326,13 +1244,14 @@
                 'type': 'git',
                 'parents': [],
                 'metadata': [],
+                'merge': False
             }
         ])
 
         self.assertEqual(
             list(mock_backend.revision_get_multiple.call_args[0][0]),
             [hex_to_hash(
-                '18d8be353ed3480476f032475e7c233eff7371d5'),
+                REVISION_ID),
              hex_to_hash(
                  'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc')])
 
@@ -1340,7 +1259,7 @@
     @istest
     def lookup_revision_multiple_none_found(self, mock_backend):
         # given
-        sha1_bin = '18d8be353ed3480476f032475e7c233eff7371d5'
+        sha1_bin = REVISION_ID
         sha1_other = 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'
 
         mock_backend.revision_get_multiple.return_value = []
@@ -1354,7 +1273,7 @@
         self.assertEqual(
             list(mock_backend.revision_get_multiple.call_args[0][0]),
             [hex_to_hash(
-                '18d8be353ed3480476f032475e7c233eff7371d5'),
+                REVISION_ID),
              hex_to_hash(
                  'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc')])
 
@@ -1364,33 +1283,12 @@
         # given
         stub_revision_log = [{
             'id': hex_to_hash('28d8be353ed3480476f032475e7c233eff7371d5'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
-            'author': {
-                'name': b'bill & boule',
-                'email': b'bill@boule.org',
-            },
-            'committer': {
-                'name': b'boule & bill',
-                'email': b'boule@bill.org',
-            },
-            'message': b'elegant fix for bug 31415957',
-            'date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
-            'committer_date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
+            'directory': DIRECTORY_ID_BIN,
+            'author': AUTHOR_ID_BIN,
+            'committer': COMMITTER_ID_BIN,
+            'message': SAMPLE_MESSAGE_BIN,
+            'date': SAMPLE_DATE_RAW,
+            'committer_date': SAMPLE_DATE_RAW,
             'synthetic': False,
             'type': 'git',
             'parents': [],
@@ -1405,22 +1303,17 @@
         # then
         self.assertEqual(list(actual_revision), [{
             'id': '28d8be353ed3480476f032475e7c233eff7371d5',
-            'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
-            'author': {
-                'name': 'bill & boule',
-                'email': 'bill@boule.org',
-            },
-            'committer': {
-                'name': 'boule & bill',
-                'email': 'boule@bill.org',
-            },
-            'message': 'elegant fix for bug 31415957',
-            'date': "2000-01-17T11:23:54+00:00",
-            'committer_date': "2000-01-17T11:23:54+00:00",
+            'directory': DIRECTORY_ID,
+            'author': AUTHOR_ID,
+            'committer': COMMITTER_ID,
+            'message': SAMPLE_MESSAGE,
+            'date': SAMPLE_DATE,
+            'committer_date': SAMPLE_DATE,
             'synthetic': False,
             'type': 'git',
             'parents': [],
             'metadata': [],
+            'merge': False
         }])
 
         mock_backend.revision_log.assert_called_with(
@@ -1432,33 +1325,12 @@
         # given
         stub_revision_log = [{
             'id': hex_to_hash('28d8be353ed3480476f032475e7c233eff7371d5'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
-            'author': {
-                'name': b'bill & boule',
-                'email': b'bill@boule.org',
-            },
-            'committer': {
-                'name': b'boule & bill',
-                'email': b'boule@bill.org',
-            },
-            'message': b'elegant fix for bug 31415957',
-            'date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
-            'committer_date': {
-                'timestamp': datetime.datetime(
-                    2000, 1, 17, 11, 23, 54,
-                    tzinfo=datetime.timezone.utc,
-                ).timestamp(),
-                'offset': 0,
-                'negative_utc': False,
-            },
+            'directory': DIRECTORY_ID_BIN,
+            'author': AUTHOR_ID_BIN,
+            'committer': COMMITTER_ID_BIN,
+            'message': SAMPLE_MESSAGE_BIN,
+            'date': SAMPLE_DATE_RAW,
+            'committer_date': SAMPLE_DATE_RAW,
             'synthetic': False,
             'type': 'git',
             'parents': [],
@@ -1473,22 +1345,17 @@
         # then
         self.assertEqual(list(actual_log), [{
             'id': '28d8be353ed3480476f032475e7c233eff7371d5',
-            'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
-            'author': {
-                'name': 'bill & boule',
-                'email': 'bill@boule.org',
-            },
-            'committer': {
-                'name': 'boule & bill',
-                'email': 'boule@bill.org',
-            },
-            'message': 'elegant fix for bug 31415957',
-            'date': "2000-01-17T11:23:54+00:00",
-            'committer_date': "2000-01-17T11:23:54+00:00",
+            'directory': DIRECTORY_ID,
+            'author': AUTHOR_ID,
+            'committer': COMMITTER_ID,
+            'message': SAMPLE_MESSAGE,
+            'date': SAMPLE_DATE,
+            'committer_date': SAMPLE_DATE,
             'synthetic': False,
             'type': 'git',
             'parents': [],
             'metadata': [],
+            'merge': False
         }])
 
         mock_backend.revision_log_by.assert_called_with(
@@ -1756,8 +1623,7 @@
         # given
         stub_rev = {
             'id': hex_to_hash('28d8be353ed3480476f032475e7c233eff7371d5'),
-            'directory': hex_to_hash(
-                '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'),
+            'directory': DIRECTORY_ID_BIN,
             'author': {
                 'name': b'ynot',
                 'email': b'ynot@blah.org',
@@ -1785,7 +1651,7 @@
 
         expected_rev = {
             'id': '28d8be353ed3480476f032475e7c233eff7371d5',
-            'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
+            'directory': DIRECTORY_ID,
             'author': {
                 'name': 'ynot',
                 'email': 'ynot@blah.org',
@@ -1811,6 +1677,81 @@
 
     @patch('swh.web.ui.service.backend')
     @istest
+    def lookup_revision_by_nomerge(self, mock_backend):
+        # given
+        stub_rev = {
+            'id': hex_to_hash('28d8be353ed3480476f032475e7c233eff7371d5'),
+            'directory': DIRECTORY_ID_BIN,
+            'author': {
+                'name': b'ynot',
+                'email': b'ynot@blah.org',
+            },
+            'parents': [
+                hex_to_hash('adc83b19e793491b1c6ea0fd8b46cd9f32e592fc')]
+        }
+
+        expected_rev = {
+            'id': '28d8be353ed3480476f032475e7c233eff7371d5',
+            'directory': DIRECTORY_ID,
+            'author': {
+                'name': 'ynot',
+                'email': 'ynot@blah.org',
+            },
+            'parents': ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'],
+            'merge': False
+        }
+
+        mock_backend.revision_get_by.return_value = stub_rev
+
+        # when
+        actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts')
+
+        # then
+        self.assertEquals(actual_revision, expected_rev)
+
+        mock_backend.revision_get_by(1, 'master2', 'some-ts')
+
+    @patch('swh.web.ui.service.backend')
+    @istest
+    def lookup_revision_by_merge(self, mock_backend):
+        # given
+        stub_rev = {
+            'id': hex_to_hash('28d8be353ed3480476f032475e7c233eff7371d5'),
+            'directory': DIRECTORY_ID_BIN,
+            'author': {
+                'name': b'ynot',
+                'email': b'ynot@blah.org',
+            },
+            'parents': [
+                hex_to_hash('adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'),
+                hex_to_hash('adc83b19e793491b1c6db0fd8b46cd9f32e592fc')
+            ]
+        }
+
+        expected_rev = {
+            'id': '28d8be353ed3480476f032475e7c233eff7371d5',
+            'directory': DIRECTORY_ID,
+            'author': {
+                'name': 'ynot',
+                'email': 'ynot@blah.org',
+            },
+            'parents': ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc',
+                        'adc83b19e793491b1c6db0fd8b46cd9f32e592fc'],
+            'merge': True
+        }
+
+        mock_backend.revision_get_by.return_value = stub_rev
+
+        # when
+        actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts')
+
+        # then
+        self.assertEquals(actual_revision, expected_rev)
+
+        mock_backend.revision_get_by(1, 'master2', 'some-ts')
+
+    @patch('swh.web.ui.service.backend')
+    @istest
     def lookup_revision_with_context_by_ko(self, mock_backend):
         # given
         mock_backend.revision_get_by.return_value = None
diff --git a/swh/web/ui/tests/views/test_api.py b/swh/web/ui/tests/views/test_api.py
--- a/swh/web/ui/tests/views/test_api.py
+++ b/swh/web/ui/tests/views/test_api.py
@@ -1443,10 +1443,10 @@
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/',
             'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233ef'
-                           'f7371d5/log/',
+            'f7371d5/log/',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6a'
-                             '42b7e2a44e6/',
+            '42b7e2a44e6/',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
@@ -1465,6 +1465,11 @@
             'synthetic': True,
         }]
 
+        expected_response = {
+            'revisions': expected_revisions,
+            'next_revs_url': None
+        }
+
         # when
         rv = self.app.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42'
                           'b7e2a44e6/log/')
@@ -1474,10 +1479,44 @@
         self.assertEquals(rv.mimetype, 'application/json')
 
         response_data = json.loads(rv.data.decode('utf-8'))
-        self.assertEquals(response_data, expected_revisions)
+        self.assertEquals(response_data, expected_response)
 
         mock_service.lookup_revision_log.assert_called_once_with(
-            '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 100)
+            '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 26)
+
+    @patch('swh.web.ui.views.api.service')
+    @istest
+    def api_revision_log_with_next(self, mock_service):
+        # given
+        stub_revisions = []
+        for i in range(27):
+            stub_revisions.append({'id': i})
+
+        mock_service.lookup_revision_log.return_value = stub_revisions[:26]
+
+        expected_revisions = [x for x in stub_revisions if x['id'] < 25]
+        for e in expected_revisions:
+            e['url'] = '/api/1/revision/%s/' % e['id']
+            e['history_url'] = '/api/1/revision/%s/log/' % e['id']
+
+        expected_response = {
+            'revisions': expected_revisions,
+            'next_revs_url': '/api/1/revision/25/log/'
+        }
+
+        # when
+        rv = self.app.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42'
+                          'b7e2a44e6/log/')
+
+        # then
+        self.assertEquals(rv.status_code, 200)
+        self.assertEquals(rv.mimetype, 'application/json')
+
+        response_data = json.loads(rv.data.decode('utf-8'))
+        self.assertEquals(response_data, expected_response)
+
+        mock_service.lookup_revision_log.assert_called_once_with(
+            '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 26)
 
     @patch('swh.web.ui.views.api.service')
     @istest
@@ -1487,7 +1526,7 @@
 
         # when
         rv = self.app.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42b7'
-                          'e2a44e6/log/?limit=10')
+                          'e2a44e6/log/')
 
         # then
         self.assertEquals(rv.status_code, 404)
@@ -1499,7 +1538,7 @@
             ' 8834ef7e7c357ce2af928115c6c6a42b7e2a44e6 not found.'})
 
         mock_service.lookup_revision_log.assert_called_once_with(
-            '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 10)
+            '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 26)
 
     @patch('swh.web.ui.views.api.service')
     @istest
@@ -1536,15 +1575,7 @@
             'synthetic': True,
         }]
 
-        # when
-        rv = self.app.get('/api/1/revision/18d8be353ed3480476f0'
-                          '32475e7c233eff7371d5/prev/prev-rev/log/')
-
-        # then
-        self.assertEquals(rv.status_code, 200)
-        self.assertEquals(rv.mimetype, 'application/json')
-        response_data = json.loads(rv.data.decode('utf-8'))
-        self.assertEquals(response_data, [
+        expected_revisions = [
             {
                 'url': '/api/1/revision/'
                 '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/',
@@ -1592,10 +1623,25 @@
                 ],
                 'type': 'tar',
                 'synthetic': True,
-            }])
+            }]
+
+        expected_response = {
+            'revisions': expected_revisions,
+            'next_revs_url': None
+        }
+
+        # when
+        rv = self.app.get('/api/1/revision/18d8be353ed3480476f0'
+                          '32475e7c233eff7371d5/prev/prev-rev/log/')
+
+        # then
+        self.assertEquals(rv.status_code, 200)
+        self.assertEquals(rv.mimetype, 'application/json')
+        response_data = json.loads(rv.data.decode('utf-8'))
+        self.assertEquals(response_data, expected_response)
 
         mock_service.lookup_revision_log.assert_called_once_with(
-            '18d8be353ed3480476f032475e7c233eff7371d5', 100)
+            '18d8be353ed3480476f032475e7c233eff7371d5', 26)
         mock_service.lookup_revision_multiple.assert_called_once_with(
             ['prev-rev'])
 
diff --git a/swh/web/ui/tests/views/test_browse.py b/swh/web/ui/tests/views/test_browse.py
--- a/swh/web/ui/tests/views/test_browse.py
+++ b/swh/web/ui/tests/views/test_browse.py
@@ -913,27 +913,30 @@
     @istest
     def browse_revision_log(self, mock_api):
         # given
-        stub_revisions = [{
-            'id': 'd770e558e21961ad6cfdf0ff7df0eb5d7d4f0754',
-            'date': 'Sun, 05 Jul 2015 18:01:52 GMT',
-            'committer': {
-                'email': 'torvalds@linux-foundation.org',
-                'name': 'Linus Torvalds'
-            },
-            'committer_date': 'Sun, 05 Jul 2015 18:01:52 GMT',
-            'type': 'git',
-            'author': {
-                'email': 'torvalds@linux-foundation.org',
-                'name': 'Linus Torvalds'
-            },
-            'message': 'Linux 4.2-rc1\n',
-            'synthetic': False,
-            'directory_url': '/api/1/directory/'
-            '2a1dbabeed4dcf1f4a4c441993b2ffc9d972780b/',
-            'parent_url': [
-                '/api/1/revision/a585d2b738bfa26326b3f1f40f0f1eda0c067ccf/'
-            ],
-        }]
+        stub_revisions = {
+            'revisions': [{
+                'id': 'd770e558e21961ad6cfdf0ff7df0eb5d7d4f0754',
+                'date': 'Sun, 05 Jul 2015 18:01:52 GMT',
+                'committer': {
+                    'email': 'torvalds@linux-foundation.org',
+                    'name': 'Linus Torvalds'
+                },
+                'committer_date': 'Sun, 05 Jul 2015 18:01:52 GMT',
+                'type': 'git',
+                'author': {
+                    'email': 'torvalds@linux-foundation.org',
+                    'name': 'Linus Torvalds'
+                },
+                'message': 'Linux 4.2-rc1\n',
+                'synthetic': False,
+                'directory_url': '/api/1/directory/'
+                '2a1dbabeed4dcf1f4a4c441993b2ffc9d972780b/',
+                'parent_url': [
+                    '/api/1/revision/a585d2b738bfa26326b3f1f40f0f1eda0c067ccf/'
+                ],
+            }],
+            'next_revs_url': '/api/1/revision/1234/log/'
+        }
         mock_api.api_revision_log.return_value = stub_revisions
 
         # when
@@ -945,6 +948,9 @@
         self.assertEqual(self.get_context_variable('sha1_git'), '426')
         self.assertTrue(
             isinstance(self.get_context_variable('revisions'), map))
+        self.assertEqual(
+            self.get_context_variable('next_revs_url'),
+            '/browse/revision/1234/log/')
         self.assertIsNone(self.get_context_variable('message'))
 
         mock_api.api_revision_log.assert_called_once_with('426', None)
diff --git a/swh/web/ui/views/api.py b/swh/web/ui/views/api.py
--- a/swh/web/ui/views/api.py
+++ b/swh/web/ui/views/api.py
@@ -705,7 +705,7 @@
 
 @app.route('/api/1/revision/<string:sha1_git>/log/')
 @app.route('/api/1/revision/<string:sha1_git>/prev/<path:prev_sha1s>/log/')
-def api_revision_log(sha1_git, prev_sha1s=None):
+def api_revision_log(sha1_git, prev_sha1s=None, limit=25):
     """Show all revisions (~git log) starting from sha1_git.
        The first element returned is the given sha1_git.
 
@@ -724,26 +724,42 @@
         NotFoundExc if the revision is not found.
 
     """
-    limit = int(request.args.get('limit', '100'))
 
-    def lookup_revision_log_with_limit(s, limit=limit):
+    response = {'revisions': None, 'next_revs_url': None}
+    revisions = None
+    next_revs_url = None
+
+    def lookup_revision_log_with_limit(s, limit=limit+1):
         return service.lookup_revision_log(s, limit)
 
     error_msg = 'Revision with sha1_git %s not found.' % sha1_git
-    rev_backward = _api_lookup(sha1_git,
-                               lookup_fn=lookup_revision_log_with_limit,
-                               error_msg_if_not_found=error_msg,
-                               enrich_fn=utils.enrich_revision)
+    rev_get = _api_lookup(sha1_git,
+                          lookup_fn=lookup_revision_log_with_limit,
+                          error_msg_if_not_found=error_msg,
+                          enrich_fn=utils.enrich_revision)
+
+    if len(rev_get) == limit+1:
+        rev_backward = rev_get[:-1]
+        next_revs_url = url_for('api_revision_log',
+                                sha1_git=rev_get[-1]['id'])
+    else:
+        rev_backward = rev_get
 
     if not prev_sha1s:  # no nav breadcrumbs, so we're done
-        return rev_backward
-
-    rev_forward_ids = prev_sha1s.split('/')
-    rev_forward = _api_lookup(rev_forward_ids,
-                              lookup_fn=service.lookup_revision_multiple,
-                              error_msg_if_not_found=error_msg,
-                              enrich_fn=utils.enrich_revision)
-    return rev_forward + rev_backward
+        revisions = rev_backward
+
+    else:
+        rev_forward_ids = prev_sha1s.split('/')
+        rev_forward = _api_lookup(rev_forward_ids,
+                                  lookup_fn=service.lookup_revision_multiple,
+                                  error_msg_if_not_found=error_msg,
+                                  enrich_fn=utils.enrich_revision)
+        revisions = rev_forward + rev_backward
+
+    response['revisions'] = revisions
+    response['next_revs_url'] = next_revs_url
+
+    return response
 
 
 @app.route('/api/1/revision'
diff --git a/swh/web/ui/views/browse.py b/swh/web/ui/views/browse.py
--- a/swh/web/ui/views/browse.py
+++ b/swh/web/ui/views/browse.py
@@ -364,8 +364,12 @@
            'revisions': []}
 
     try:
-        revisions = api.api_revision_log(sha1_git, prev_sha1s)
+        revision_data = api.api_revision_log(sha1_git, prev_sha1s)
+        revisions = revision_data['revisions']
+        next_revs_url = revision_data['next_revs_url']
         env['revisions'] = map(utils.prepare_data_for_view, revisions)
+        env['next_revs_url'] = utils.prepare_data_for_view(next_revs_url)
+
     except (NotFoundExc, BadInputExc) as e:
         env['message'] = str(e)